Fatih Doğmuş

Modern Java - Günümüzde Java

Bu makale, Modern Java serisinin bir parçası. Serideki diğer makaleler:
  1. Modern Java - Günümüzde Java (bu makale)

Java, hiç olmadığı kadar hızlı bir şekilde değişiyor. Her altı ayda bir yeni sürüm çıkıyor ve her sürümde ne özelliği geldiğini takip etmesi zor bir hale geliyor. Bu sebeple bir yazı dizisi hazırlayarak modern Java’dan bahsetmek istedim. Bu yazı dizisinde Java’nın yeni release cadence’ından, Java 8 ‘den sonra gelen modern özelliklerden ve mevcuttaki geliştirilmekte olan ve gelecekte gelecek özelliklerden bahsedeceğim.

Bu serinin ilk yazısı olan bu makalede ise temelleri atıp, günümüzde Java’nın nasıl geliştirildiğinden ve farklı JDK’ler arasında fark olup olmadığından bahsedeceğim. Aynı zamanda ‘Java paralı mı?’ sorusuna da cevap vereceğim.

İçindekiler

İlk başta gelin şu JDK kafa karışıklığına bir son verelim.

JDK’ler, her yerde JDK’ler

Günümüzde canı sıkılan yeni bir JDK çıkarıyor gibi hissediyorum. Bu tabii ki kötü bir şey değil, Java’nın canlı olduğunu ve pek çok farklı opsiyonun olduğunu gösterir. Fakat bazı zamanlar takip etmek ve seçim yapma konusunda problem yaşayabiliyoruz. O yüzden ilk başta JDK üzerindeki karmaşıklığı gidermek istiyorum.

OpenJDK

İlk başta OpenJDK mayın tarlasına girmeden ne olduğunu tanımlayalım isterseniz.

OpenJDK, aslında bir projeden ve kaynak koddan ibaret. Proje, JDK’e yeni özellikle katmak için bir yönetim aracı. Java’ya giren tüm özellikler, bu projeden ve JEP’ler(Java Enhancement Proposal’lar) aracılığı ile oluyor. OpenJDK’in proje kısmı, bu JEP’leri yönetmek ve JEP’ler etrafında dönen konuşmaları takip etmek ve issue tracking gibi işler için kullanılıyor.

Kaynak kodlar ise yapılan bu işlerin toplandığı kaynak kodlar. Kabul edilen değişiklikler GitHub üzerindeki yukarıda verdiğim repository’de yapılıyor. Yani OpenJDK, Java’nın referans implementation’ı diyebiliriz. OpenJDK kendiliğinde bir binary, yani günlük kullanabileceğimiz bir executable vermiyor. İndirip kurabileceğimiz ve üzerinde geliştirme yapabileceğimiz elle tutulur bir şey yok.

Bize kullanabileceğimiz ve geliştirme yapabileceğimiz JDK’ler verenler, farklı vendor’lar, farklı firmalar oluyor.

Oracle JDK vs Open JDK

Eskiden, Java’yı bilgisayarınıza kurmak istediğinizde gittiğiniz tek adres, Oracle’ın sitesi oluyordu. Oradan doğrudan Java’yı indirip kurup geliştirme yapmaya başlayabiliyordunuz. Fakat günümüzde durum bu kadar kolay değil.

Aslında OpenJDK eskiden beri var. Java’nın açık kaynak yapıldığı günden beri Oracle, Open JDK’in kurulabilir binary’lerini sunuyor. Fakat geçmişte OpenJDK kullanmak çok mantıklı değildi. Bunun sebebi ise Oracle JDK, yani doğrudan Oracle’ın sunduğu JDK, Open JDK’den özellik bakımından daha üstündü. Öyle olunca kimse Open JDK kullanmıyordu. Fakat son yıllarda olan gelişmelerle birlikte bu durum değişti.

Oracle, Java 9 ile beraber Open JDK ile Oracle JDK arasındaki farkları kapatacağını söyledi. Bunun için de Oracle JDK’in içinde olup Open JDK’de olmayan özellik ve kütüphaneleri açık kaynak yapıp yayınlamaya karar verdiler. Bu kütüphaneler içerisinde JMC, JFR, JavaFX, javax gibi pek çok kütüphane bulunuyor. Bunları her yeni versiyonda aşama aşama Oracle JDK’den çıkarıp open source olarak ayrıyeten yayınladılar. Bunun sonucunda da Java 11’den sonra Oracle JDK ile Open JDK arasında özellik bakımından herhangi bir fark kalmadı.

Aslında yalan söyledim, aralarında bir fark var. Fakat bu fark, özellik bakımından değil, lisans bakımından. Open JDK, açık kaynak GPL lisansını kullanırken, Oracle JDK ise commercial bir lisans kullanıyor. Bunun anlamı, Java 11’den sonra eğer Oracle’ın JDK’lerini kullanmak istiyorsanız(yani Oracle’ın kendi sitesinden indirilen JDK), Oracle’a para vermek zorundasınız. Eğer production’da Oracle JDK 11 ve sonrasını kullanıp, herhangi bir para vermiyorsanız bir sıkıntı var demektir 🙂 Yasal olarak bu tespit edilirse ciddi para cezası alma ihtimaliniz var. O yüzden bir java -version yapıp, JDK’inizi kimden indirdiğinize bakmanızı tavsiye ederim.

Bunun anlamı, artık default Oracle JDK değil, Open JDK. Fakat Open JDK’i indirmenin pek çok farklı yolu var, ona da birazdan değineceğim. Bence bu şekilde yaparak Oracle kendi ayağına sıktı gibime geliyor. Çünkü anketlerde giderek Oracle JDK’in pazar payı düşerken, farklı Open JDK dağıtımlarının oranı artıyor. Bunun da lisans almaya ciddi anlamda etkisi olacağını düşünüyorum.

Yeni release cadence

Şimdi gelin yeni yayım politikasından bahsedelim.

Eski durum

Java 10’dan önce, Java versiyonları büyük özellikler etrafında şekilleniyordu. Mesela Java 8’deki lambda function’lar ve stream’ler, Java 9’daki modül sistemi gibi. Böyle olunca da sürümlerin yayımlanması tamamıyle bu özelliklerin yetişmesine bağlı oluyor ve yayım süreleri çok uzayabiliyor. Java 8’in yayınlanması 3 yıl, Java 9’un yayınlanması ise 3.5 yıl sürdü. Bunun da pek çok dezavantajı bunuluyor.

Hazır olan feature’lare beklemek zorunda kalıyor

Bu üç yıllık sürede biten pek çok irili ufaklı özellik oluyor. Fakat bunların son kullanıcının eline ulaşması için yıllarca beklemesi gerekiyor. Yazılım sektöründen biliyoruz ki bir özellik kullanıcının eline ne kadar çabuk ulaşırsa o kadar iyi oluyor.

Geri bildirim çok geç oluyor

Yukardaki sebebin bir sonucu olarak, hazır olan bir feature hakkında geri bildirim almak çok zor bir hale geliyor. Ara sıra erken erişim adı altında o ana dek master’a merge’lenmiş özelliklerin sunulduğu hazır olmayan bir JDK yayınlanıyor olsa da, bunu genellikle çok az bir kesim kullanıp geri bildirim verdiği için yeterince geri bildirim toplanamıyordu.

Daha ufak özellikler önemsenmiyor

Şimdi düşünün ki elinizde iki ihtimal var: Ya ufak tefek, geliştiricinin hayatını derinden etkilemeyecek özellikler ile uğraşabilirsiniz ya da lambda function’lar gibi devasa özelliklerle uğraşabilirsiniz.

Böyle bir seçimle karşılaşınca tabii ki Oracle da ikinciyi seçiyordu. Fakat bu, Java’nın diğer modern dillerden çok daha geri kalmasını ve kotlin, swift gibi dillerdeki geliştiricinin hayatında ufak da olsa güzel değişiklikler yapacak özellikler için vakit bulunmuyordu. Java geliştiricileri de daha modern dillere kedinin ciğere baktığı gibi bakıyor, hatta farklı dillere geçmeyi bile düşünüyordu.

Yeni durum

Durum böyle olunca, Oracle radikal bir karar aldı ve her altı ayda bir yeni bir sürüm çıkarma kararı aldı.

Her yılın mart ve eylül aylarında, yeni bir Java versiyonu yayınlanıyor. Hangi feature’ın girdiği hiç önemli değil, sürüm treni hiç kimseyi beklemiyor. Eğer bir feature, sürüme girmek için hazırsa giriyor, yok hazır değilse hiç kimse beklenmiyor ve “6 ay sonra gel” deniyor ve sonraki sürüme erteleniyor.

Bu aslında continious delivery’nin en temeli: Sürümü özellikler etrafında şekillendirmek yerine özellikleri sürüm etrafında şekillendirmek.

Bu zekice karar sonrasında Java’da pek çok avantaj ortaya çıktı:

Hazır olan feature’lar beklemek zorunda değil

Release treni her altı ayda bir kaktığı için, hazır olan feature’lar en geç 6 ay içerisinde geliştiricinin eline ulaşabiliyor.

Geri bildirim döngüsü çok hızlı oluyor Özellikler daha hızlı teslim edildiği için artık çok daha rahat bir şekilde geri bildirim toplanabiliyor.

Ufak özelliklere üvey evlat muamelesi yapılmıyor

Artık bir özelliğin 3 yıl beklemesi gerekmediği için daha ufak özellikler de öz çocuk muamelesi görüyorlar.

Bence tek bir kötü yanı ise artık Java release’leri eskisi kadar heyecan uyandırmıyor. Her altı ayda bir sürüm çıktığı için “hııı yine yeni sürüm çıkmış” gibi bir hava oluyor. Ama getirdiği şeylerin yanında bu biraz daha kapris olarak kalıyor 🙂

Daha hızlı geri bildirim almak için mekanizmalar

Oracle hızlı geri bildirim almak için sadece altı ayda bir sürüm almakla kalmadı. Aynı zamanda yeni bir preview özelliği getirerek kullanıcıların geliştirilmekte olan özellikleri daha rahat test edebilmeleri için güzel bir mekanizma sağladılar.

Preview özelliği, henüz tam olarak Java’nın içerisine girecek kadar olgun olmayan özellikler hakkında geri bildirim almak için oluşturulmuş bir mekanizma. Bir özellik, resmi olarak yayınlanmadan önce, dil içerisine preview feature olarak giriyor. Bu özellikler, ana JDK içerisine merge ediliyorlar, fakat default olarak bu özelliklere erişemiyorsunuz. Mesela Java 14’te records özelliği preview olarak gelmişti. Bu özellikleri kullanabilmek için, kodunuzu compile ederken --enable-preview flag’ine paslamanız gerekiyor.

Bu flag’i pasladığınızda, bir nevi erken erişime açılmış olan özellikleri, başka herhangi ek bir şey yapmadan deneme ve geri bildirim verme şansınız oluyor. Bundan evvel bu tarz yeni özellikleri deneyebilmek için apayrı early access build bir JDK indirmeniz gerekiyordu. Hepimiz sanırım birden fazla JDK’i yönetmenin ne kadar zor olduğunu biliyoruz. (Allah Windows’ta path işini çıkaranı bildiği gibi yapsın 😠)

Bu yöntem ile erken erişime açılan özelliklerin denenmesi ve geri bildirim alınması çok daha kolay bir hale geliyor.

Yeni versiyonlara yükseltme ve destek planı

Şimdi bu kadar versiyon olunca tabii kafa karışıklıkları ve sorular da beraberinde geliyor. İlk akla gelen soru ise ‘Java paralı mı oldu?‘. Şimdiden söyleyeyim de rahatlayın: Java paralı olmadı arkadaşlar 🙂

Bunu aradan çıkarttıktan sonra nasıl olduğuna bakalım isterseniz. İlk başta gelin şu LTS muhabbetinden bahsedeyim.

LTS dediğimiz şey Long term supoort demek, yani uzun süreli destek. Eskiden Oracle, her Java versiyonu için yıllarca destek sağlıyordu. Bu destekler genellikle bug fix ve güvenlik yamaları oluyordu fakat çok nadiren de olsa ufak tefek feature’ları eski versiyona getiriyorlardı.

Fakat çok fazla versiyon yayınlandığı için her versiyona tek tek tüm bug fix ve güvenlik yamalarını getirmek büyük dert olacaktır. Bu sebeple Oracle, tüm sürümlere değil, bazı sürümlere uzun dönem destek vereceğini açıkladı. Bu sürümler her 6 sürümde bir olacak. İlk LTS’in Java 11 olduğunu düşünürsek sonraki LTS sürümü 17, sonraki ise 23 diye gidiyor. Bu sürümlere Oracle uzun süreli destek vereceğini duyuruldu. Diğer sürümler ise, bir sonraki sürüm çıktıktan sonra destekleri kesilecek, yani ilk çıktıktan 6 ay sonra bu ‘ara’ sürümler herhangi bir güncelleme almayacaklar.

Hal böyle olunca kafalar karışıyor. Bir şekilde bizim bug fix ve güvenlik yamalarını almamız gerekiyor, öbür türlü ciddi bir güvenlik açığı oluşma riski var. Ama burada da para vermemiz gerekebilir, Oracle kamyon yüküyle para isteyecektir gibi farklı sorular geliyor akla. Merak etmeyin, tek tek cevaplayacağım inşallah bu soruları.

Yükseltme planı

Şimdi önümüzde iki alternatif var: Her altı ayda bir yeni versiyona geçme veya LTS versiyonlarında kalıp gelen yamaları uygulama.

LTS versiyonlarında kalıp yamaları uygulamak

İlk opsiyon, LTS versiyonlarında kalıp yamalar geldikçe bu yamaları uygulamak. Bu biraz daha “güvenli” bir opsiyon, çünkü her versiyonda bir şeylerin kırılma riski bulunuyor. Tüm kod tabanında tekrar tekrar bir şeyleri değiştirmek zorunda kalmadan stabilitenizi koruyabilirsiniz.

Her altı ayda bir güncelleme

Eğer bu yöntemi seçerseniz, güncellemeleri almak için her altı ayda bir Java versiyonunu güncellemeniz gerekiyor. Mesela siz Java 16 ile başladınız, Java 17 çıktığında kısa bir süre içerisinde Java 17’ye geçmeniz gerekiyor, çünkü 16, Java 17 çıktıktan sonra herhangi bir güncelleme almayacak. Bu yöntem biraz daha “riskli” zira versiyonlar arasında eğer breaking change bulunuyorsa her güncellemede bu değişiklikler ile uğraşmanız gerekecek.

Benim kişisel görüşüm ise her altı ayda bir güncellemek daha mantıklı. Bunu iki sebebi var:

  1. Java gerçekten çok stabil bir dil. Versiyonlar arasında breaking change çok çok az bulunuyor. Ancak kullanmamanız gereken bir API kullanıyorsanız bu değişikliklerden etkileniyorsunuz. O yüzden de versiyon güncellediğinizde tek satır kod değiştirmeden güncellemeyi yapabilmeniz kuvvetle muhtemel.
  2. LTS’de kalsanız bile güvenlik yamalarını kurmak için yine geliştirme ortamlarındaki, CI/CD ortamında ve production’daki JDK kurulumlarını değiştirmeniz gerekecek. Bu kadar uğraşmışken neden yeni versiyonla gelen özellikleri kullanmayasınız 🙂

Fakat altı ayda bir güncellemenize en büyük engel muhtemelen kendi kodunuz değil, yan etmenler olacaktır. Eğer kullandığınız kütüphane, yeni Java versiyonunu desteklemiyorsa veya kullandığınız IDE henüz son Java versiyonunu desteklemiyorsa, güncellemeniz mümkün olmuyor. Bu muhtemelen sizin kendi kodunuzun kırılmasından daha yüksek ihtimal ve daha büyük bir risk. Çünkü özellikle büyük kütüphaneler, bazı “magic” işlemlerini yapabilmek için JDK’in derinlerindeki özellikleri kullanabiliyorlara. Bu özellikler de Java takımı tarafında implementation detail olarka görüldüğü için, değiştirilmeleri daha yüksek ihtimalli oluyor. Bu da bu tarz büyük kütüphanelerin kod tabanlarında Java versiyon yükseltmesi yapıldığında bir şeylerin kırılma ihtimalini artırıyor.

Genellikle spring, hibernate, tomcat gibi büyük kütüphaneler Java’nın bu yeni yayım politikasına adapte oldular. Genellikle yeni Java versiyonu genel olarak yayınlanmadan bu tarz kütüphaneler yeni versiyonu destekliyorlar. Fakat her türlü bu kütüphanelerin yeni Java versiyonunu desteklemesini beklemeniz gerekiyor ve destek geldiğinde kütüphane versiyonunu da yükseltmeniz gerekiyor. Bu da bir risk ve yükseltme planına dahil edilmesi gereken başka bir iş olarak ekleniyor.

Tabii ki her kütüphanenin değişiklik yapmasına gerek olmuyor, eğer Java’nın içerisinde değişen bir şeye depend etmiyorlarsa bir şey değiştirmelerine gerek olmuyor. Ama bu tarz riskler yükseltmeden önce kendi kod tabanınızda deneyip kendinizin görmesi gereken şeyler.

Bu tarz riskler olduğu için genellikle LTS sürümlerinde kalınması öneriliyor. Ben buna katılmıyorum, bence Java çok stabil bir dil olduğu için %95 kod tabanlarının herhangi bir değişiklik yapmadan yükseltebileceğini düşünüyorum. Ama yine de bunları kendiniz deneyim edip ona göre karar vermeniz gerekiyor.

LTS destek planı

Eğer her altı ayda bir yükseltmek yerine LTS versiyonlarından kalmaya karar verdiyseniz önünüzde iki ihtimal var: Ya para vererek bu desteği alabilirsiniz ya da para vermeden.

Para vererek destek

Bu opsiyon biraz daha bir sözleşmeye bağlı olarak kullandığı yazılımlar için destek aldığını göstermesi gereken şirketler için geçerli. İlla telefon ettiğimde destek alabileyim derseniz veya bunu sözleşme imzaladığınız yer sizden isterse, bu durum mantıklı.

Para vererek destek alabileceğiniz pek çok yer bulunuyor. Bunlar Oracle, Azul, IBM ve RedHat. Tüm bu firmalar Oracle’ın LTS olarak işaretlemiş olduğu sürümlerde bug fix ve güvenlik yamalarını kendi sundukları JDK’lere getirmeyi garanti ediyorlar. Bu şekilde her altı ayda bir yükseltmeden güvenlik risklerinden kurtulmuş oluyorsunuz.

Para vermeden destek

Eğer yukarıda saydığım gibi bir zorunluluğunuz yoksa beleşten destek almanız da çok mümkün. RedHat, yaptığı bir açıklamada ücretsiz olarak LTS’den sonraki sürümlerde yapılan hata çözümleri ve güvenlik yamalarını Open JDK’e ücretsiz olarak merge edeceklerini ve bu şekilde herkese ücretsiz olarak destek vereceklerini açıkladı. Şimdi bu tarz bir ücretsiz destek imkanı varken kim kamyon dolusu para verip destek almak ister bilmiyorum açıkçası 🙂

Bu desteği almak için herhangi bir Open JDK distribution’ını kullanıyor olmanız yeterli.

Open JDK distribution’ları

Bahsettiğim gibi Open JDK’in doğrudan sunmuş olduğu bir binary yok. Bir vendor’dan bu binary leri indirmeniz gerekiyor. Burada sayacağım JDK’lerin tamamı ücretsiz ve açık kaynaklıdır. O yüzden bu JDK’lerden herhangi birini kullandığınız zaman herhangi bir kimseye para vermenize gerek yok. Hatta bir LTS sürümü kullanıyorsanız RedHat’in yukarıda bahsettiğim OpenJDK’e sunmuş olduğu ücretsiz destekten otomatik olarak yararlanıyorsunuz.
Bu vendor’lar ise:

Bu yukarıda verdiğim JDK’lerin birbirinden özellik bakımından zerre farkı bulunmuyor(sadece alibaba’nın JDK’inde çok ciddi farklar var, ama onun da fazlası var eksiği yok, ekstra özellikler için kendi sayfasına bakabilirsiniz). Hepsi Open JDK’in source code’unda oluşturulan yüklenebilen binary’ler, sadece şirtketlerin kendilerince yaptıkları bir kaç bug fix bulunuyor, fakat bu bug fix’ler de zaman içerisinde diğer tüm Open JDK distribution’lara geleceği için hangisini seçtiğiniz çok önemli olmuyor, seçim size kalmış.

Ama benim favorim de community’nin favorisi de AdoptOpenJDK’den, zira yüklemesi çok çok kolay bir hale getirmişler ve arkalarında ciddi bir destek var. Hatta yakın vakitte Eclipse Foundation’a katıldıklarını duyurdular. Bu da çok daha iyi bir destek anlamına geliyor.

Kapanış

Bu yazımda Java’nın günümüzdeki durumundan ve farklı JDK’lerin ne anlama geldiğinden bahsettim. Bu release cadence ilk yayınlandığında herkesin aklında olan ‘Java paralı mı?’ sorusuna da net bir cevap verdiğimi düşünüyorum.

Yazı dizimin sonraki ayağında, Java 8’den sonra gelen özellikleri masaya yatırıp tek tek bizim hayatımızda neler değiştirdiğine bakacağım.

Eğer sorunuz, öneriniz veya yorumunuz varsa aşağıya yorum olarak eklerseniz çok memnun olurum.

İlerideki blog yazılarımı takip edebilmek için twitter’dan beni takip etmeyi unutmayın.

Sonraki blog yazısında görüşünceye kadar Allah’a emanet olun!